package hsmoto.core
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.geom.Rectangle;
	
	import hsmoto.UIContainer.Group;
	import hsmoto.data.PropertyInfo;
	
	[Event(name="Event.RESIZE", type="flash.events.Event")]
	/**
	 * 自动布局的基类，只有当它放到Group类里，相对布局属性才会生效，
	 * 并且属性不会马上生效，需要在exit-frame才会生效，避免用循环时
	 * 进行大量重复运算
	 * 你可以把它作为桥梁，让普通显示对象拥有相对布局属性，
	 * 放到此类显示列表的对象在更改大小和位置的属性后，应该调用此类的
	 * addToUpdateDisplayList方法，如果想自动更新请使用Group类
	 * @author Zhang
	 */
	public class UIComponent extends UISprite
	{
		/**
		 * 相对于舞台的深度
		 */
		private var _depth:int;
		private var _lastHorizontalSet:PropertyInfo
		private var _lastVerticalSet:PropertyInfo;

		public function UIComponent()
		{
			_lastHorizontalSet = new PropertyInfo();
			_lastHorizontalSet.setInfo("x", 0);
			_lastVerticalSet = new PropertyInfo();
			_lastVerticalSet.setInfo("y", 0);

			this.addEventListener(Event.ADDED_TO_STAGE, added);
			this.addEventListener(Event.REMOVED_FROM_STAGE, removed);
		}

		protected function removed(event:Event):void
		{
			_depth = 0;
		}

		protected function added(event:Event):void
		{
			countDepth(this, this.parent);
		}
		
		public function addToUpdateDisplayList():void
		{
			if(this.parent is Group)
				(this.parent as Group).addToUpdateDisplayList();
		}

		override protected function childAdd(child:DisplayObject):void
		{
			addToUpdateDisplayList();
		}

		override protected function childRemove(child:DisplayObject):void
		{
			addToUpdateDisplayList();
		}
		/**
		 * 通过递归计算自己的深度
		 */
		private function countDepth(ui:UIComponent, parent:DisplayObjectContainer):void
		{
			if(parent is Stage)
				return;
			ui._depth = ui._depth + 1;
			countDepth(ui, parent.parent);
		}
		/**
		 * 重写Sprite的宽度属性，使其设置后不会随子元件的变化而变化
		 */
		override public function set width(value:Number):void
		{
			this.scrollRect = new Rectangle(0, 0, value, this.height);
			this.dispatchEvent(new Event(Event.RESIZE));
			Tool.updataSize(this);
			addToUpdateDisplayList();
		}
		/**
		 * 重写Sprite的高度属性，使其设置后不会随子元件的变化而变化
		 */
		override public function set height(value:Number):void
		{
			this.scrollRect = new Rectangle(0, 0, this.width, value);
			this.dispatchEvent(new Event(Event.RESIZE));
			Tool.updataSize(this);
			addToUpdateDisplayList();
		}
		
		private var _x:Number = 0;
		
		override public function set x(value:Number):void
		{
			_lastHorizontalSet.setInfo("x", value);
			addToUpdateDisplayList();
			_x = value;
		}
		
		override public function get x():Number
		{
			return _x;
		}
		
		private var _y:Number = 0;
		
		override public function set y(value:Number):void
		{
			_lastVerticalSet.setInfo("y", value);
			addToUpdateDisplayList();
			_y = value;
		}
		
		override public function get y():Number
		{
			return _y;
		}
		/**
		 * 直接设置自己的x属性(程序自动调用，尽量不要设置)
		 */
		final public function set currentX(value:Number):void
		{
			super.x = value;
			_x = x;
		}
		/**
		 * 直接设置自己的y属性(程序自动调用，尽量不要设置)
		 */
		final public function set currentY(value:Number):void
		{
			super.y = value;
			_y = y;
		}
		/**
		 * 自己顶部到父容器顶部的距离
		 */
		public function set top(value:Number):void
		{
			_lastVerticalSet.setInfo("top", value);
			addToUpdateDisplayList();
		}
		/**
		 * 自己底部到父容器底部的距离
		 */
		public function set bottom(value:Number):void
		{
			_lastVerticalSet.setInfo("bottom", value);
			addToUpdateDisplayList();
		}
		/**
		 * 自己左边到父容器左边的距离
		 */
		public function set left(value:Number):void
		{
			_lastHorizontalSet.setInfo("left", value);
			addToUpdateDisplayList();
		}
		/**
		 * 自己右边到父容器右边的距离
		 */
		public function set right(value:Number):void
		{
			_lastHorizontalSet.setInfo("right", value);
			addToUpdateDisplayList();
		}
		/**
		 * 自己中心到父容器中心的垂直距离
		 */
		public function set verticalCenter(value:Number):void
		{
			_lastVerticalSet.setInfo("verticalCenter", value);
			addToUpdateDisplayList();
		}
		/**
		 * 自己中心到父容器中心的水平距离
		 */
		public function set horizontalCenter(value:Number):void
		{
			_lastHorizontalSet.setInfo("horizontalCenter", value);
			addToUpdateDisplayList();
		}
		/**
		 * 相对于舞台的深度
		 */
		public function get depth():int
		{
			return _depth;
		}
		/**
		 * 水平方向的最后一次设置的属性
		 */
		public function get lastHorizontalSet():PropertyInfo
		{
			return _lastHorizontalSet;
		}
		/**
		 * 垂直方向的最后一次设置的属性
		 */
		public function get lastVerticalSet():PropertyInfo
		{
			return _lastVerticalSet;
		}
	}
}
